package com.ehsunbehravesh.mypasswords.entity;

import com.ehsunbehravesh.mypasswords.Domain;
import com.ehsunbehravesh.mypasswords.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

public class PasswordTag {

  private int id;
  private String title;

  //<editor-fold defaultstate="collapsed" desc="Constructors & Destructors">
  public PasswordTag(String title) {
    this.title = title.toLowerCase();
  }

  public PasswordTag(int id, String title) {
    this.id = id;
    this.title = title.toLowerCase();
  }
  //</editor-fold>

  //<editor-fold defaultstate="collapsed" desc="Getters & Setters">
  public int getId() {
    return id;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title.toLowerCase();
  }
  //</editor-fold>

  //<editor-fold defaultstate="collapsed" desc="Methods">
  public PasswordEntry[] readEntries() {
    ArrayList<PasswordEntry> passwords = new ArrayList<PasswordEntry>();
    Domain domain = Domain.getInstance();
    Connection con = domain.getDBConnection();
    ResultSet rs = null;

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = String.format("SELECT * FROM PASSWORD_ENTRY pe INNER JOIN PASSWORD_ENTRY_PASSWORD_TAG pept "
                + "ON (pe.ID = pept.PASSWORD_ENTRY_ID) WHERE pept.PASSWORD_TAG_ID = %d ORDER BY pe.title", this.id);

        rs = st.executeQuery(sql);

        while (rs.next()) {
          PasswordEntry password = new PasswordEntry(rs.getInt("id"), rs.getString("title"), rs.getString("url"),
                  rs.getString("description"), rs.getString("username"), rs.getString("password"));
          passwords.add(password);
        }
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
      } finally {
        try {
          if (rs != null) {
            rs.close();
          }
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
        }
      }
    }

    PasswordEntry[] arrPasswords = new PasswordEntry[passwords.size()];
    arrPasswords = passwords.toArray(arrPasswords);
    return arrPasswords;
  }

  public boolean save() {
    Domain domain = Domain.getInstance();
    Connection con = domain.getDBConnection();

    if (con != null) {
      try {
        PreparedStatement st = null;
        String sql = "";
        if (this.id <= 0) {
          sql = String.format("INSERT INTO PASSWORD_TAG (TITLE) "
                  + "VALUES ('%s')", this.title);          
        } else {
          sql = String.format("UPDATE PASSWORD_TAG SET TITLE = '%s' "
                  + "WHERE ID = %d", this.title, this.id);
        }

        st = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

        int result = st.executeUpdate();
        if (this.id <= 0) {
          ResultSet rs = st.getGeneratedKeys();
          if (rs.next())
            this.id = rs.getInt(1);
        }

        return result == 1;
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return false;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return false;
        }
      }
    } else {
      return false;
    }
  }

  @Override
  public String toString() {
    return title + " (" + readEntries().length + ")";
  }

  public boolean load() {
    Domain domain = Domain.getInstance();
    Connection con = domain.getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = String.format("SELECT * FROM PASSWORD_TAG WHERE ID = %d", this.id);

        ResultSet rs = st.executeQuery(sql);
        if (rs.next()) {
          this.id = rs.getInt("ID");
          this.title = rs.getString("TITLE");
        }
        return true;
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return false;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return false;
        }
      }
    } else {
      return false;
    }
  }

  public boolean loadByTitle() {
    Domain domain = Domain.getInstance();
    Connection con = domain.getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = String.format("SELECT * FROM PASSWORD_TAG WHERE TITLE = '%s'", this.title);

        ResultSet rs = st.executeQuery(sql);
        if (rs.next()) {
          this.id = rs.getInt("ID");
          this.title = rs.getString("TITLE");
        }
        return true;
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return false;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return false;
        }
      }
    } else {
      return false;
    }
  }

  public boolean delete() {
    Domain domain = Domain.getInstance();
    Connection con = domain.getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = String.format("DELETE FROM PASSWORD_TAG WHERE ID = %d", this.id);

        st.executeUpdate(sql);
        return true;
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return false;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return false;
        }
      }
    } else {
      return false;
    }
  }
  //</editor-fold>

  //<editor-fold defaultstate="collapsed" desc="Static Methods">
  public static PasswordTag[] getAllTags() {
    ArrayList<PasswordTag> tags = new ArrayList<PasswordTag>();

    Domain domain = Domain.getInstance();
    Connection con = domain.getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = "SELECT * FROM PASSWORD_TAG ORDER BY title";

        ResultSet rs = st.executeQuery(sql);
        while (rs.next()) {
          PasswordTag tag = new PasswordTag(rs.getInt("id"), rs.getString("title"));
          tags.add(tag);
        }        
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
        }
      }
    }

    PasswordTag[] arrTags = new PasswordTag[tags.size()];
    arrTags = tags.toArray(arrTags);

    return arrTags;
  }

  public static void cleanTags() {
    PasswordTag[] allTags = getAllTags();
    for (int i = 0; i < allTags.length; i++) {
      PasswordTag passwordTag = allTags[i];
      PasswordEntry[] passwords = passwordTag.readEntries();
      if (passwords.length <= 0) {
        passwordTag.delete();
      }
    }
  }
  //</editor-fold>
}
